function createHoverSelectBox(/*HTMLDocument*/ doc) {
    var div = doc.createElement("div");
    div.id = "hover-select-box";
    doc.body.appendChild(div);
    return new SelectBox(div, "red");
}

function clearQuerySelectBoxes(/*HTMLDocument*/doc) {
    var lastChild = doc.body.lastChild;
    
    if (!lastChild) return;
    if (lastChild.id != "query-select-boxes") {
        var div = doc.createElement("div");
        div.id = "query-select-boxes";
        doc.body.appendChild(div);
        return;
    }
    $(lastChild).empty();
}

function createQuerySelectBoxes(/*HTMLDocument*/ doc, 
                                /*Array[HTMLElement]*/ nodes) {
    clearQuerySelectBoxes(doc);
    var rootNode = doc.body.lastChild;
    
    for (var i=0; i < nodes.length; i++) {
        var sbox = new SelectBox(rootNode, "green");
        sbox.select(nodes[i]);
    }
}

function SelectBox(/*HTMLElement*/ rootNode, /*string*/ color) {
    this.color = color;
    
    var arry = new Array(4);
    // Create four DIV elements underneath the rootNode:
	for (var i=0; i < 4; i++) {
		var div = rootNode.ownerDocument.createElement("div");
		$(div).css({backgroundColor: color, position: 'absolute', 
		            width: 0, height: 0, zIndex: 999});
		$(rootNode).append(div);
		arry[i] = div;
	}
    [this.left, this.top, this.right, this.bottom] = arry;
    this.nodes = [];
}

// This function is also used by the widen and narrow methods
SelectBox.prototype._select = function(/*HTMLElement*/ node) {
    var n = $(node);
    var offset = n.offset();
    
    $(this.left).css({left: offset.left - 2,
                      top: offset.top, 
                      width: 2, 
                      height: n.height()});
                      
    $(this.top).css({left: offset.left-2,
                     top: offset.top-2, 
                     width: n.width() + 4, 
                     height: 2});					 
                
    $(this.right).css({left: offset.left+n.width(),
                       top: offset.top, 
                       width: 2, 
                       height: n.height()});
                  
    $(this.bottom).css({left: offset.left-2,
                        top: offset.top+n.height(), 
                        width: n.width() + 4, 
                        height: 2});
                        
    return node;
}

SelectBox.prototype.select = function(/*HTMLElement*/ node) {
    this.nodes = [this._select(node)];
};

SelectBox.prototype.deselect = function() {
    [this.left, this.top, this.right, this.bottom].forEach(function(node) {
        $(node).css({width: 0, height: 0});
    });
};

SelectBox.prototype.widen = function() {
    var last = this.nodes[this.nodes.length - 1];
    var parent = last.parentNode;
    
    if (parent.nodeName == "HTML") return last;
    
    this.nodes.push(parent);
    this._select(parent);
    return parent;
};

SelectBox.prototype.narrow = function() {
    if (this.nodes.length == 1)
        return this.nodes[0];

    this.nodes.pop();            
    var last = this.nodes[this.nodes.length - 1];
    this._select(last);
    return last;
};
